//编写libevent服务端
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <event2/event.h>
#define MAX 10


struct event_fd
{
	evutil_socket_t fd;
	struct event* ev;
}eventfd[MAX];


void readcb(evutil_socket_t fd,short events,void* arg)
{
		
	printf("有数据信号到来\n");
	int n;
	char buf[1024];
	memset(buf,0,sizeof(buf));
	n = read(fd,buf,sizeof(buf));
	if(n <= 0)
	{
		close(eventfd[fd].fd);
		//下地基
		event_del(eventfd[fd].ev);
		return;
	}
	if(n>0)
	{
		printf("buf==[%s]\n",buf);
		write(fd,buf,n);
	}
}


void conncb(evutil_socket_t fd,short events,void* arg)
{

	printf("有连接信号到来\n");
	struct event_base * base = (struct event_base*)arg;
	int cfd = accept(fd,NULL,NULL);
	eventfd[cfd].fd = cfd;
	if(cfd > 0)    //建立连接
	{
		//将事件继续上base

		eventfd[cfd].ev = event_new(base,cfd,EV_READ | EV_PERSIST,readcb,NULL);
		if(eventfd[cfd].ev == NULL)
		{
			close(cfd);
			printf("event_base error\n");
			exit(0);
		}
		//上地基
		event_add(eventfd[cfd].ev,NULL);
	}
}

int main()
{
	//创建socket
	int lfd = socket(AF_INET, SOCK_STREAM, 0);

	//设置端口复用
	int opt = 1;
	setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

	//绑定
	struct sockaddr_in serv;
	bzero(&serv, sizeof(serv));
	serv.sin_addr.s_addr = htonl(INADDR_ANY);
	serv.sin_port = htons(6666);
	serv.sin_family = AF_INET;
	bind(lfd, (struct sockaddr*)&serv, sizeof(serv));

	//监听
	listen(lfd, 120);

	//创建地基
	struct event_base *base = event_base_new();
	if(base == NULL)
	{
		printf("event_base_new error\n");
		return -1;
	}	
	//创建事件，监听文件描述符对应的事件
	struct event *ev = event_new(base,lfd,EV_READ | EV_PERSIST,conncb,base);
	if(ev == NULL)
	{
		printf("event_new error\n");
		return -1;
	}
	//将事件上地基
	event_add(ev,NULL);

	//进入事件循环等待
	event_base_dispatch(base);

	//释放资源
	event_base_free(base);
	event_free(ev);

	close(lfd);



	return 0;
}
